(in-package :ortho-complex)

;; Base type converters
;;;;;;;;;;;;;;;;;;;;;;;

(defun polar->complex (x)
  (let ((mag (complex-polar::magnitude x))
	(angle (complex-polar::angle x)))
    (complex (* mag (cos angle))
	     (* mag (sin angle)))))

(defun square (x)
  (expt x 2))

(defun complex->polar (x)
  (let ((real (realpart x))
	(imag (imagpart x)))
    (complex-polar::make-complex
     (sqrt (+ (square real) (square imag)))
     (atan imag real))))

(add-ortho-type 'complex-polar
		#'complex->polar
		#'polar->complex)

;; Function wrappers
;;;;;;;;;;;;;;;;;;;;

;(defun mult (x y)
;  (let ((pol-x (base->type 'complex-polar x))
;        (pol-y (base->type 'complex-polar y)))
;    (type->base 'complex-polar
;                (complex-polar::mult pol-x pol-y))))

(defmacro define-simple-ortho-fun (name base-function-name arguments type)
  (let ((converted-arguments (loop for argument in arguments
				   collect `(base->type ',type
							,argument)))
	(args (gensym "args")))
    `(defun ,name ,arguments
       (let ((,args (list ,@converted-arguments)))
	 (type->base ',type
		     (apply #',base-function-name ,args))))))

(define-simple-ortho-fun mult complex-polar::mult (x y)
  complex-polar)